package service

import (
	"context"
	"log"
	"nearby/biz/common"
	"nearby/biz/dal/db/po"
	"nearby/biz/dal/db/repo"
	"nearby/biz/domain/entity"
	domainService "nearby/biz/domain/service"
	"nearby/biz/model"
	"nearby/biz/model/vo"
)

type GetMomentsService struct {
}

func (ss *GetMomentsService) Execute(ctx context.Context, req *model.GetMomentsRequest) (*model.GetMomentsResponse, error) {
	if req.Limit == 0 {
		req.Limit = 40
	}

	momentDomainService := &domainService.MomentService{}
	momentsResp, err := momentDomainService.GetMoments(ctx, domainService.GetMomentsRequest{
		ViewerID: ss.GetUserID(ctx),
		Limit:    req.Limit,
		Offset:   req.Offset,
	})
	if err != nil {
		return nil, common.NewBizErr(common.BizErrCode, "好像来到了一片荒原?", err)
	}
	momentEntities := momentsResp.Moments

	err = ss.LoadInfos(ctx, momentEntities)
	if err != nil {
		log.Printf("GetMomentsService report, ss.LoadInfos fail, err: %+v", err)
	}

	return &model.GetMomentsResponse{
		Meta:   common.MetaOk,
		Moment: ss.ToVos(ctx, momentsResp.Moments),
		Total:  momentsResp.Total,
	}, nil
}

func (ss *GetMomentsService) GetUserID(ctx context.Context) int64 {
	user := common.GetUser(ctx)
	if user == nil {
		return 0
	}
	return user.UserID
}

func (ss *GetMomentsService) ToVos(ctx context.Context, moments []*entity.Moment) []*vo.Moment {
	momentVos := make([]*vo.Moment, len(moments))
	for i := range momentVos {
		momentVo := moments[i].ToVo()
		momentVos[i] = &momentVo
	}
	return momentVos
}

func (ss *GetMomentsService) LoadInfos(ctx context.Context, entities []*entity.Moment) error {
	err := ss.LoadUserInfos(ctx, entities)
	if err != nil {
		return err
	}
	ss.LoadUserLikeInfos(ctx, entities)
	return nil
}

func (ss *GetMomentsService) GetUserIDs(ctx context.Context, entities []*entity.Moment) (userIDs []int64) {
	userIDs = make([]int64, 0)
	bitMap := make(map[int64]bool)
	for i := range entities {
		bitMap[entities[i].User.UserID] = true
	}
	for userID := range bitMap {
		userIDs = append(userIDs, userID)
	}
	return userIDs
}

func (ss *GetMomentsService) LoadUserInfos(ctx context.Context, momentEntities []*entity.Moment) error {
	userIDs := ss.GetUserIDs(ctx, momentEntities)
	// 1. 获取userPos
	userRepo := repo.NewUserRepo(ctx)
	userPos, err := userRepo.GetUserPos(ctx, userIDs)
	if err != nil {
		return err
	}
	// 2. 整合到userMap里
	userMap := make(map[int64]*po.User)
	for i := range userPos {
		userMap[userPos[i].UserID] = userPos[i]
	}
	// 3. 将用户信息装载到momentEntities
	for i := range momentEntities {
		userID := momentEntities[i].User.UserID
		info := userMap[userID]
		if info != nil {
			momentEntities[i].User.Nickname = userMap[userID].Nickname
			momentEntities[i].User.HeadURL = userMap[userID].HeadURL
		}
	}
	return nil
}

func (ss *GetMomentsService) LoadUserLikeInfos(ctx context.Context, entities []*entity.Moment) {

}
